﻿package frEngine.shader.filters.vertexFilters
{
    import baseEngine.system.*;
    import frEngine.shader.*;
    import frEngine.shader.filters.*;

    public class TransformFilter extends VertexFilter
    {
        public var OpType:int;

        public function TransformFilter(param1:Boolean = false, param2:int = 4)
        {
            super(FilterType.Transform);
            useAlpha = param1;
            this.OpType = param2;
            return;
        }// end function

        override public function setRegisterParams(param1:Program3dRegisterInstance) : void
        {
            return;
        }// end function

        override public function get programeId() : String
        {
            return "optype" + this.OpType + ",useAlpha:" + useAlpha + ",transform";
        }// end function

        override public function createFragmentColor(param1:Program3dRegisterInstance, param2:Boolean) : String
        {
            var _loc_3:String = "";
            if (useAlpha)
            {
                _loc_3 = _loc_3 + "mul           {output}       \t  \t\t{output}  \t\t  \t\t{v_vertexAlpha}.x\t\t\t\n";
            }
            return _loc_3;
        }// end function

        override public function clone() : FilterBase
        {
            return new TransformFilter(this.useAlpha, this.OpType);
        }// end function

        override public function createVertexCode(param1:Program3dRegisterInstance, param2:int) : String
        {
            var _loc_3:String = "";
            if (param2 > 0)
            {
                _loc_3 = this.createSkinTransform(param1, param2);
            }
            else
            {
                _loc_3 = this.createNoSkinTransform(param1);
            }
            param1.OpType = this.OpType;
            return _loc_3;
        }// end function

        private function createNoSkinTransform(param1:Program3dRegisterInstance) : String
        {
            var _loc_2:String = "";
            var _loc_3:* = new Array();
            if (useAlpha)
            {
                _loc_3.push(new ToBuilderInfo("va1", FilterName.POSITION, false, 4));
                _loc_3.push(new ToBuilderInfo("vf0", "{v_vertexAlpha}", false, 1));
                _loc_2 = _loc_2 + "mov           {output}    \t\t\tva1           \t\t \n";
                _loc_2 = _loc_2 + "mov           vf0    \t\t\t\tva1.w          \t \n";
                _loc_2 = _loc_2 + "mov           {output}.w    \t\t{vcConst1}.z       \n";
            }
            else
            {
                _loc_3.push(new ToBuilderInfo("va1", FilterName.POSITION, false, 3));
                _loc_2 = _loc_2 + "mov           {output}    \t\t\tva1           \t\t \n";
                _loc_2 = _loc_2 + "mov           {output}.w    \t\t{vcConst1}.z       \n";
            }
            _loc_2 = param1.toBuild(_loc_2, _loc_3);
            return _loc_2;
        }// end function

        private function createSkinTransform(param1:Program3dRegisterInstance, param2:int) : String
        {
            if (param2 >= 4)
            {
                throw new Error("最大骨骼数应为3");
            }
            var _loc_3:String = "mov           vt0           vc0 \t\t\t\t\t\n";
            switch(param2)
            {
                case 1:
                {
                    _loc_3 = _loc_3 + ("m34           vt0.xyz       va3         \t vc[va1.x]   \t\t\n" + "mul           vt0       \tvt0           va2.x         \t\t\n");
                    break;
                }
                case 2:
                {
                    _loc_3 = _loc_3 + ("m34           vt0.xyz       va3         \t vc[va1.x]   \t\t\n" + "mul           vt2       \t vt0           va2.x         \t\n" + "m34           vt0.xyz       va3         \t vc[va1.y]   \t\t\n" + "mul           vt3           vt0           va2.y         \t\n" + "add           vt0.xyz       vt2           vt3           \t\n");
                    break;
                }
                case 3:
                {
                    _loc_3 = _loc_3 + ("m34           vt0.xyz       va3         \t vc[va1.x]   \t\t\n" + "mul           vt2       \t vt0           va2.x         \t\n" + "m34           vt0.xyz       va3         \t vc[va1.y]   \t\t\n" + "mul           vt3           vt0           va2.y         \t\n" + "m34           vt0.xyz       va3         \t vc[va1.z]   \t\t\n" + "mul           vt4           vt0           va2.z         \t\n" + "add           vt0.xyz       vt2           vt3           \t\n" + "add           vt0.xyz       vt4           vt0           \t\n");
                    break;
                }
                default:
                {
                    break;
                }
            }
            _loc_3 = _loc_3 + ("mov           vt0.w         {vcConst1}.z         \t\t\t\t\t\n" + "mov         \t {output}      vt0           \t\t\t\t\t\t\t\n");
            var _loc_4:Array = [new ToBuilderInfo("vc1-105", "{bones}", false, Device3D.maxBonesPerSurface * 3 + 1, []), new ToBuilderInfo("va1", FilterName.SKIN_INDICES, false, param2), new ToBuilderInfo("va2", FilterName.SKIN_WEIGHTS, false, param2), new ToBuilderInfo("va3", FilterName.POSITION, false, 3)];
            _loc_3 = param1.toBuild(_loc_3, _loc_4);
            return _loc_3;
        }// end function

    }
}
